package dk.au.cs.bdsi.mail.resources;

import static dk.au.cs.bdsi.mail.representation.Representation.MEDIA_TYPE;

import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;

import dk.au.cs.bdsi.core.activities.DeleteException;
import dk.au.cs.bdsi.core.activities.UpdateException;
import dk.au.cs.bdsi.core.representation.InvalidRepresentationException;
import dk.au.cs.bdsi.core.resources.CoreResource;
import dk.au.cs.bdsi.mail.activities.CreateMailActivity;
import dk.au.cs.bdsi.mail.activities.DeleteMailActivity;
import dk.au.cs.bdsi.mail.activities.NoSuchMailException;
import dk.au.cs.bdsi.mail.activities.ReadMailActivity;
import dk.au.cs.bdsi.mail.activities.UpdateMailActivity;
import dk.au.cs.bdsi.mail.domain.Mail;
import dk.au.cs.bdsi.mail.representation.MailRepresentation;

/**
 * Mail resource, with which clients can interact to run the
 * application protocol.
 */
@Path("/mail")
public class MailResource extends CoreResource {
	@POST
	@Path("/")
	@Consumes(MEDIA_TYPE)
	@Produces(MEDIA_TYPE)
	public Response createMail(String messageRepresentation) {
		try {
			Mail message = MailRepresentation.fromXml(messageRepresentation).getMail();
			MailRepresentation response = new CreateMailActivity().create(message, requestUri());
			return Response.created(response.getSelfLink().getUri()).entity(response).build();
		} catch (InvalidRepresentationException e) {
			return Response.status(Status.BAD_REQUEST).build();
		} catch (Exception e) {
			return Response.serverError().build();
		}
	}
	
	@GET
	@Path("/{messageId}")
	@Produces(MEDIA_TYPE)
	public Response getMail() {
		try {
			MailRepresentation response = new ReadMailActivity().retrieve(requestUri());
			return Response.ok().entity(response).build();
		} catch (NoSuchMailException e) {
			return Response.status(Status.NOT_FOUND).build();
		} catch (Exception e) {
			return Response.serverError().build();
		}
	}
	
	@POST
	@Path("/{messageId}")
	@Consumes(MEDIA_TYPE)
	@Produces(MEDIA_TYPE)
	public Response updateMail(String messageRepresentation) {
		try {
			Mail message = MailRepresentation.fromXml(messageRepresentation).getMail();
			MailRepresentation response = new UpdateMailActivity().update(message, requestUri());
			return Response.ok().entity(response).build();
		} catch (InvalidRepresentationException e) {
			return Response.status(Status.BAD_REQUEST).build();
		} catch (NoSuchMailException e) {
			return Response.status(Status.NOT_FOUND).build();
		} catch (UpdateException e) {
			return Response.status(Status.CONFLICT).build();
		} catch (Exception e) {
			return Response.serverError().build();
		}
	}
	
	@DELETE
	@Path("/{messageId}")
	@Produces(MEDIA_TYPE)
	public Response deleteMail() {
		try {
			MailRepresentation response = new DeleteMailActivity().delete(requestUri());
			return Response.ok().entity(response).build();
		} catch (NoSuchMailException e) {
			return Response.status(Status.NOT_FOUND).build();
		} catch (DeleteException e) {
			// {@link http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html}
			return Response.status(405).header("Allow", "GET").build();
		} catch (Exception e) {
			return Response.serverError().build();
		}
	}
}
